package com.sunnada.wfs.utils;

import lombok.Data;
import org.apache.commons.lang.StringUtils;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.fluent.Executor;
import org.apache.http.client.fluent.Form;
import org.apache.http.client.fluent.Request;
import org.apache.http.entity.ContentType;

import java.io.IOException;
import java.util.Map;

@Data
public class HttpUtil {

    private static String accept = "application/json;charset=UTF-8";

    /**
     * 不带参数的get请求
     * @param url 地址
     * @return 响应体内容
     * @throws IOException
     */
    public static String get(String url) throws IOException {
        Request request = Request.Get(parseGet(url,null));
        addHeader(request);
        return request(request,null,null);
    }

    /**
     * 带参数的get请求
     * @param url 地址
     * @param param 参数
     * @return 响应体内容
     * @throws IOException
     */
    public static String get(String url,Map<String,String> param) throws IOException {
        Request request = Request.Get(parseGet(url,param));
        addHeader(request);
        return request(request,null,null);
    }

    /**
     * 带身份校验的get请求
     * @param url 地址
     * @param param 参数
     * @param userName 用户名
     * @param password 密码
     * @return 响应体内容
     * @throws IOException
     */
    public static String get(String url,Map<String,String> param,String userName,String password)  throws IOException {
        Request request = Request.Get(parseGet(url,param));
        addHeader(request);
        return request(request,userName,password);
    }

    /**
     * 将get请求的参数解析成字符串的形式
     * @param url 地址
     * @param param 参数
     * @return 解析成字符串形式的get请求
     */
    private static String parseGet(String url,Map<String,String> param){
        StringBuilder p = new StringBuilder();
        p.append(url);
        if (param!=null&&param.size()!=0){
            p.append("?");
            for(Map.Entry<String,String> entry : param.entrySet()){
                p.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
            }
        }
        String s = p.toString();
        if (s.endsWith("&")) s=s.substring(0,s.length()-1);
        return s;
    }

    /**
     * 提交form表单的post请求
     * @param url 地址
     * @param param form表单参数
     * @return 响应体内容
     * @throws IOException
     */
    public static String postForm(String url,Map<String,String> param) throws IOException {
        return postForm(url,param,null,null);
    }

    /**
     * 带身份校验的form表单的post请求
     * @param url 地址
     * @param param form表单参数
     * @param userName 用户名
     * @param password 密码
     * @return 返回响应体内容
     * @throws IOException
     */
    public static String postForm(String url,Map<String,String> param,String userName,String password) throws IOException {
        Form form = Form.form();
        if (param!=null) param.forEach(form::add);
        Request request = Request.Post(url).bodyForm(form.build());
        addHeader(request);
        return request(request,userName,password);
    }

    /**
     * Post请求
     * @param url   请求地址
     * @param content 请求内容
     * @param contentType 请求内容类型，例：ContentType.APPLICATION_XML
     * @return 返回响应体内容
     * @throws IOException
     */
    public static String postString(String url,String content,ContentType contentType) throws IOException {
        return postString(url, content, contentType,null,null);
    }

    /**
     * Post请求
     * @param url   请求地址
     * @param content 请求内容
     * @param contentType 请求内容类型，例：ContentType.APPLICATION_XML
     * @param userName 用户名
     * @param password 密码
     * @return 返回响应体内容
     * @throws IOException
     */
    public static String postString(String url,String content,ContentType contentType,String userName,String password) throws IOException {
        Request request = Request.Post(url).bodyString(content,contentType);
        addHeader(request);
        return request(request,userName,password);
    }

    private static void addHeader(Request request){
        if (StringUtils.isNotBlank(accept)) request.addHeader("Accept",accept);
    }

    /**
     * 执行请求
     * @param request 请求
     * @param userName 用户名
     * @param password 密码
     * @return 返回响应体内容
     * @throws IOException
     */
    private static String request(Request request,String userName,String password)  throws IOException {
        Executor executor = Executor.newInstance();
        if (StringUtils.isNotBlank(userName)&&StringUtils.isNotBlank(password)){
            UsernamePasswordCredentials creds = new UsernamePasswordCredentials(userName,password);
            executor.auth(AuthScope.ANY,creds);
        }
        return executor.execute(request).returnContent().asString();
    }


    public static void main(String[] args) throws IOException {
//        Executor executor = Executor.newInstance();
//        UsernamePasswordCredentials creds = new UsernamePasswordCredentials("admin","geoserver");
//        executor.auth(AuthScope.ANY,creds);
//        System.out.println(executor.execute(Request.Get("http://localhost:8080/geoserver/rest/workspaces/test/datastores")).returnContent().asString());
        System.out.println(get("http://localhost:8080/geoserver/rest/workspaces",null,"admin","geoserver"));
    }
}
